﻿using SoftwareConsulting.BI11.NumericalMethods.Interfaces;

namespace SoftwareConsulting.BI11.NumericalMethods.DhbFunctionEvaluation
{    
    /// <summary>
    /// Класс приближенного вычисления производной функции
    /// </summary>
    public sealed class FunctionDerivative : IOneVariableFunction
    {        
        private IOneVariableFunction _originalFunction;        
        private double _relativePrecision; //относительная погрешность

        /// <summary>
        /// Конструктор класса
        /// </summary>
        /// <param name="originalFunction"></param>
        public FunctionDerivative(IOneVariableFunction originalFunction)
            : this(originalFunction, 0.000001)
        {
        }

        /// <summary>
        /// Конструктор класса
        /// </summary>
        /// <param name="originalFunction"></param>
        /// <param name="relativePrecision"></param>
        public FunctionDerivative(IOneVariableFunction originalFunction, double relativePrecision)
        {
            _originalFunction = originalFunction;
            _relativePrecision = relativePrecision;
        }

        /// <summary>
        /// Возвращает значение производной для указанного аргумента
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public double GetValue(double x)
        {
            double x1 = x == 0 ? _relativePrecision : x * (1 + _relativePrecision);
            double x2 = 2 * x - x1;
            return (_originalFunction.GetValue(x1) - _originalFunction.GetValue(x2)) / (x1 - x2);
        }
    }
}
